﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using System.Data.SqlClient;
using System.IO;
using System.Reflection;
using System.Linq.Expressions;
using System.Runtime.Serialization;
using System.Transactions;
using System.Threading;

namespace Taobao.Backup
{
    public partial class BackupForm : Form
    {
        protected const int MaxCountEachRotate = 10;

        #region Ctor 
        
        public BackupForm()
        {
            InitializeComponent();
        }

        #endregion

        #region Button Events
        Thread thread;
        private void StartMaintainButton_Click(object sender, EventArgs e)
        {
            thread = new Thread(Run);
            thread.IsBackground = true;
            thread.Start();
        }

        protected void Run()
        {
            ClearOutput();
            Console.WriteLine("开始备份数据库：");
            if (BackupDataBase())
            {
                Console.WriteLine("备份数据库成功！");

                //
                Console.WriteLine("开始拷贝数据");
                CopyData();
                Console.WriteLine("拷贝数据结束");
            }
            else
            {
                Console.WriteLine("备份数据库失败，程序终止，请检查原因后，重新运行！");
            }
        }
        #endregion

        #region Assist Methods

        protected bool BackupDataBase()
        {
            try
            {
                ConnectionStringSettings cnnStrSettings = ConfigurationManager.ConnectionStrings["backupMasterConnectionString"];
                SqlConnectionStringBuilder cnnStrBulider = new SqlConnectionStringBuilder(cnnStrSettings.ConnectionString);
                DBBackup.MSSQLDatabase database = new DBBackup.MSSQLDatabase();
                database.ServerName = cnnStrBulider.DataSource;
                database.UserName = cnnStrBulider.UserID;
                database.Password = cnnStrBulider.Password;
                database.LoginSecure = cnnStrBulider.IntegratedSecurity;
                 
                string toBackupDataBaseName = ConfigurationManager.AppSettings["backupDb"];
                string toBackupPath = ConfigurationManager.AppSettings["backupDbPath"];
                toBackupPath = Path.Combine(toBackupPath, toBackupDataBaseName + DateTime.Now.ToString("yyyy_MM_dd_hh_mm_ss") + ".bak");

                return database.Backup(toBackupDataBaseName, toBackupPath); 
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return false;
        }
        
        string toBackupCnnString = ConfigurationManager.ConnectionStrings["toBackupConnectionString"].ConnectionString;
        string backupToCnnString = ConfigurationManager.ConnectionStrings["taobaotool_backupEntities"].ConnectionString;
          

        protected void CopyData()
        {
            CopyShop();
            CopySender();
            CopyRefund();
            CopyDistributor();
            CopyTrade();
             
        }

        protected void CopyShop()
        {
            Console.WriteLine("更新 Shop 开始");
            try
            {
                using (TaobaoModelContainer toBackupContainer = new TaobaoModelContainer(toBackupCnnString))
                {
                    using (BackupModel.taobaotool_backupEntities backupToContainer = new BackupModel.taobaotool_backupEntities(backupToCnnString))
                    {
                        var allEntitiesInBackup = toBackupContainer.CreateObjectSet<Shop>();
                        var allBackupToEntities = backupToContainer.CreateObjectSet<BackupModel.Shop>();
                        Console.WriteLine(string.Format("总共{0}条Shop记录要备份.",allEntitiesInBackup.Count()));
                        foreach (var oldentity in allEntitiesInBackup)
                        {
                            try
                            {
                                var entity = (from s in backupToContainer.Shops where s.ShopId == oldentity.ShopId select s).FirstOrDefault();
                                bool needAdd = entity == null;
                                if (needAdd)
                                {
                                    entity = allBackupToEntities.CreateObject();
                                }
                                CloneObject<Shop, BackupModel.Shop>(oldentity, entity, needAdd);
                                if (needAdd)
                                {
                                    allBackupToEntities.AddObject(entity);
                                    Console.WriteLine(string.Format("插入 {0}：{1} into {2}", typeof(Shop).Name, entity.ShopId, "备份数据库"));
                                }
                                else
                                {
                                    Console.WriteLine(string.Format("更新 {0}：{1} into {2}", typeof(Shop).Name, entity.ShopId, "备份数据库"));
                                }
                                backupToContainer.SaveChanges();
                            }
                            catch (Exception ex1)
                            {
                                Console.WriteLine(ex1.Message);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.WriteLine("更新 Shop 结束");
            Console.WriteLine();
        
        }

        protected void CopySender()
        {
            Console.WriteLine("更新 Sender 开始");
            try
            {
                using (TaobaoModelContainer toBackupContainer = new TaobaoModelContainer(toBackupCnnString))
                {
                    using (BackupModel.taobaotool_backupEntities backupToContainer = new BackupModel.taobaotool_backupEntities(backupToCnnString))
                    {
                        var allEntitiesInBackup = toBackupContainer.CreateObjectSet<Sender>();
                        var allBackupToEntities = backupToContainer.CreateObjectSet<BackupModel.Sender>();
                        Console.WriteLine(string.Format("总共{0}条Sender记录要备份.", allEntitiesInBackup.Count()));
                        foreach (var oldentity in allEntitiesInBackup)
                        {
                            try
                            {
                                var entity = (from s in allBackupToEntities where s.SenderID == oldentity.SenderID select s).FirstOrDefault();
                                bool needAdd = entity == null;
                                if (needAdd)
                                {
                                    entity = allBackupToEntities.CreateObject();
                                }
                                CloneObject<Sender, BackupModel.Sender>(oldentity, entity, needAdd);
                                if (needAdd)
                                {
                                    allBackupToEntities.AddObject(entity);
                                    Console.WriteLine(string.Format("插入 {0}：{1} into {2}", typeof(Sender).Name, entity.SenderID, "备份数据库"));
                                }
                                else
                                {
                                    Console.WriteLine(string.Format("更新 {0}：{1} into {2}", typeof(Sender).Name, entity.SenderID, "备份数据库"));
                                }
                                backupToContainer.SaveChanges();
                            }
                            catch (Exception ex1)
                            {
                                Console.WriteLine(ex1.Message);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.WriteLine("更新 Sender 结束");
            Console.WriteLine();
        }

        protected void CopyRefund()
        {
            Console.WriteLine("更新 Refund 开始");
            var totalCount = 0;
            var rotateCount = 0;
            var currentRotate = 0;
            try
            {
                using (TaobaoModelContainer toBackupContainer = new TaobaoModelContainer(toBackupCnnString))
                {
                    totalCount = (from s in toBackupContainer.Refunds
                                  where s.Modified <= BackupDateFrom
                                  select s).Count();
                    if (totalCount > MaxCountEachRotate)
                    {
                        rotateCount = totalCount / MaxCountEachRotate + ((totalCount % MaxCountEachRotate) > 0 ? 1 : 0);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.WriteLine(string.Format("总共{0}条 Refund 记录要备份.", totalCount));
            for (currentRotate = 0; currentRotate < rotateCount; currentRotate++)
            {
                Console.WriteLine(string.Format("开始备份 第{0}页 of {1} 页 Refund 记录.", currentRotate+1,rotateCount));
                try
                {
                    using (TaobaoModelContainer toBackupContainer = new TaobaoModelContainer(toBackupCnnString))
                    {
                        //using (TransactionScope scope = new TransactionScope())
                        {
                            var allEntitiesInBackup = toBackupContainer.CreateObjectSet<Refund>();
                            var entitiesNeedBackup = allEntitiesInBackup.Where(s => s.Modified <= BackupDateFrom)
                                .OrderBy(s => s.ID).Skip(currentRotate * MaxCountEachRotate).Take(MaxCountEachRotate).ToList();

                            foreach (var oldentity in entitiesNeedBackup)
                            {
                                try
                                {
                                    using (BackupModel.taobaotool_backupEntities backupToContainer = new BackupModel.taobaotool_backupEntities(backupToCnnString))
                                    {
                                        var allBackupToEntities = backupToContainer.CreateObjectSet<BackupModel.Refund>();
                                        var entity = (from s in allBackupToEntities
                                                      where s.RefundID == oldentity.RefundID
                                                      select s).FirstOrDefault();
                                        bool needAdd = entity == null;
                                        if (needAdd)
                                        {
                                            entity = allBackupToEntities.CreateObject();
                                        }
                                        CloneObject<Refund, BackupModel.Refund>(oldentity, entity, needAdd);
                                        if (needAdd)
                                        {
                                            allBackupToEntities.AddObject(entity);
                                            Console.WriteLine(string.Format("插入 {0}：{1} into {2}", typeof(Refund).Name, entity.RefundID, "备份数据库"));
                                        }
                                        else
                                        {
                                            Console.WriteLine(string.Format("更新 {0}：{1} into {2}", typeof(Refund).Name, entity.RefundID, "备份数据库"));
                                        }
                                        //allEntitiesInBackup.DeleteObject(oldentity);
                                        backupToContainer.SaveChanges();
                                    }
                                }
                                catch (Exception ex1)
                                {
                                    Console.WriteLine(ex1.Message);
                                }
                            }
                            toBackupContainer.SaveChanges();
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            Console.WriteLine("更新 Refund 结束");
            Console.WriteLine();
        }
                
        protected void CopyDistributor( )
        {
            Console.WriteLine("更新 Distributor 开始");
            try
            {
                using (TaobaoModelContainer toBackupContainer = new TaobaoModelContainer(toBackupCnnString))
                {
                    using (BackupModel.taobaotool_backupEntities backupToContainer = new BackupModel.taobaotool_backupEntities(backupToCnnString))
                    {
                        var allEntitiesInBackup = toBackupContainer.CreateObjectSet<Distributor>();
                        var allBackupToEntities = backupToContainer.CreateObjectSet<BackupModel.Distributor>();

                        Console.WriteLine(string.Format("总共{0}条Distributor记录要备份.", allEntitiesInBackup.Count()));
                        foreach (var oldentity in allEntitiesInBackup)
                        {
                            try
                            {
                                var entity = (from s in allBackupToEntities where s.distributor_id == oldentity.distributor_id select s).FirstOrDefault();
                                bool needAdd = entity == null;
                                if (needAdd)
                                {
                                    entity = allBackupToEntities.CreateObject();
                                }
                                CloneObject<Distributor, BackupModel.Distributor>(oldentity, entity, needAdd);
                                if (needAdd)
                                {
                                    allBackupToEntities.AddObject(entity);
                                    Console.WriteLine(string.Format("插入 {0}：{1} into {2}", typeof(Distributor).Name, entity.distributor_id, "备份数据库"));
                                }
                                else
                                {
                                    Console.WriteLine(string.Format("更新 {0}：{1} into {2}", typeof(Distributor).Name, entity.distributor_id, "备份数据库"));
                                }
                                backupToContainer.SaveChanges();
                            }
                            catch (Exception ex1)
                            {
                                Console.WriteLine(ex1.Message);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.WriteLine("更新 Distributor 结束");
            Console.WriteLine();
        }

        protected void CopyOutSend()
        {
            Console.WriteLine("更新 OutSent 开始");
            try
            {
                using (TaobaoModelContainer toBackupContainer = new TaobaoModelContainer(toBackupCnnString))
                {
                    using (BackupModel.taobaotool_backupEntities backupToContainer = new BackupModel.taobaotool_backupEntities(backupToCnnString))
                    {
                        var allEntitiesInBackup = toBackupContainer.CreateObjectSet<OutSent>();
                        var allBackupToEntities = backupToContainer.CreateObjectSet<BackupModel.OutSent>();

                        foreach (var oldentity in allEntitiesInBackup.Where(
                                                      s => 
                                                          s.Message == "发货成功"))
                        {

                            {
                                try
                                {
                                    var entity = (from s in allBackupToEntities
                                                  where s.OutSentId == oldentity.OutSentId
                                                  select s).FirstOrDefault();
                                    bool needAdd = entity == null;
                                    if (needAdd)
                                    {
                                        entity = allBackupToEntities.CreateObject();
                                    }
                                    CloneObject<OutSent, BackupModel.OutSent>(oldentity, entity, needAdd);
                                    if (needAdd)
                                    {
                                        allBackupToEntities.AddObject(entity);
                                        Console.WriteLine(string.Format("插入 {0}：{1} into {2}", typeof(OutSent).Name, entity.OutSentId, "备份数据库"));
                                    }
                                    else
                                    {
                                        Console.WriteLine(string.Format("更新 {0}：{1} into {2}", typeof(OutSent).Name, entity.OutSentId, "备份数据库"));
                                        //Console.WriteLine(string.Format("删除 {0}：{1} from {2}", typeof(OutSent).Name, entity.OutSentId, "原来的数据库"));
                                    }
                                    allEntitiesInBackup.DeleteObject(oldentity);
                                    backupToContainer.SaveChanges();
                                }
                                catch (Exception ex1)
                                {
                                    Console.WriteLine(ex1.Message);
                                }

                            }
                        }
                    }
                    toBackupContainer.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.WriteLine("更新 OutSent 结束");
            Console.WriteLine();
        }

        protected void CopyTrade()
        {
            Console.WriteLine("更新 Trade 开始");

            var totalCount = 0;
            var rotateCount = 0;
            var currentRotate = 0;  
            try
            {
                using (TaobaoModelContainer toBackupContainer = new TaobaoModelContainer(toBackupCnnString))
                {
                    totalCount = (from s in toBackupContainer.Trades
                                 where (s.Status == "TRADE_FINISHED" || s.Status == "TRADE_CLOSED_BY_TAOBAO" || s.Status == "TRADE_CLOSED")
                                     && s.Process > 0 && s.ProcessTime < BackupDateFrom && s.ProcessTime != null
                                     && s.endtime != null && s.endtime < BackupDateFrom
                                     && s.PayTime < BackupDateFrom
                                 select s).Count();  
                    if (totalCount > MaxCountEachRotate)
                    {
                        rotateCount = totalCount / MaxCountEachRotate + ((totalCount % MaxCountEachRotate) > 0 ? 1 : 0);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.WriteLine(string.Format("总共{0}条Trade记录要备份.", totalCount));
            for (currentRotate = 0; currentRotate < rotateCount; currentRotate++)
            {
                Console.WriteLine(string.Format("开始备份 第{0}页 of {1} 页 Trade 记录.", currentRotate + 1, rotateCount));
                try
                {
                    using (TaobaoModelContainer toBackupContainer = new TaobaoModelContainer(toBackupCnnString))
                    {
                        using (BackupModel.taobaotool_backupEntities backupToContainer = new BackupModel.taobaotool_backupEntities(backupToCnnString))
                        {
                            var allEntitiesInBackup = toBackupContainer.CreateObjectSet<Trade>();
                            var allBackupToEntities = backupToContainer.CreateObjectSet<BackupModel.Trade>();
                            var allTradesNeedBackup = (from s in toBackupContainer.Trades
                                                       where (s.Status == "TRADE_FINISHED" || s.Status == "TRADE_CLOSED_BY_TAOBAO" || s.Status == "TRADE_CLOSED")
                                                           && s.Process > 0 && s.ProcessTime < BackupDateFrom && s.ProcessTime != null
                                                           && s.endtime != null && s.endtime < BackupDateFrom
                                                           && s.PayTime < BackupDateFrom
                                                           orderby s.Tid
                                                       select s).Skip(currentRotate * MaxCountEachRotate).Take(MaxCountEachRotate).ToList();

                            foreach (var oldentity in allTradesNeedBackup)
                            {
                                try
                                {
                                    var entity = (from s in allBackupToEntities
                                                  where s.Tid == oldentity.Tid
                                                  select s).FirstOrDefault();
                                    bool needAdd = entity == null;
                                    if (needAdd)
                                    {
                                        entity = allBackupToEntities.CreateObject();
                                    }
                                    CloneObject<Trade, BackupModel.Trade>(oldentity, entity, needAdd);
                                    if (needAdd)
                                    {
                                        allBackupToEntities.AddObject(entity);
                                    }
                                    CopyOrderInfo(toBackupContainer, backupToContainer, entity.Tid);
                                    CopyOutSentInfo(toBackupContainer, backupToContainer, entity.Tid);
                                    if (needAdd)
                                    {
                                        Console.WriteLine(string.Format("插入 {0}：{1} into {2}", typeof(Trade).Name, entity.Tid, "备份数据库"));
                                        allEntitiesInBackup.DeleteObject(oldentity);
                                        Console.WriteLine(string.Format("删除 {0}：{1} from {2}", typeof(Trade).Name, entity.Tid, "原来的数据库"));
                                    }
                                    else
                                    {
                                        Console.WriteLine(string.Format("更新 {0}：{1} into {2}", typeof(OutSent).Name, entity.Tid, "备份数据库"));
                                        allEntitiesInBackup.DeleteObject(oldentity);
                                        Console.WriteLine(string.Format("删除 {0}：{1} from {2}", typeof(Trade).Name, entity.Tid, "原来的数据库"));
                                    }
                                    backupToContainer.SaveChanges();
                                }
                                catch (Exception ex1)
                                {
                                    Console.WriteLine(ex1.Message);
                                }
                            }
                        }
                        toBackupContainer.SaveChanges();
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            Console.WriteLine("更新 Trade 结束");
            Console.WriteLine();
        }

        protected void CopyOrderInfo(TaobaoModelContainer toBackupContainer, BackupModel.taobaotool_backupEntities backupToContainer, Int64 tid)
        {
            Console.WriteLine(string.Format("更新 交易 {0} 中的 订单信息 开始",tid));
            try
            {
                var allEntitiesInBackup = toBackupContainer.CreateObjectSet<OrderInfo>();
                var allBackupToEntities = backupToContainer.CreateObjectSet<BackupModel.OrderInfo>();

                foreach (var oldentity in allEntitiesInBackup.Where(o=>o.Trade == tid).ToList())
                {
                    try
                    {
                        var entity = (from s in allBackupToEntities
                                      where s.OrderID == oldentity.OrderID 
                                      select s).FirstOrDefault();
                        bool needAdd = entity == null;
                        if (needAdd)
                        {
                            entity = allBackupToEntities.CreateObject();
                        }
                        CloneObject<OrderInfo, BackupModel.OrderInfo>(oldentity, entity, needAdd);
                        if (needAdd)
                        {
                            allBackupToEntities.AddObject(entity);
                            Console.WriteLine(string.Format("插入 {0}：{1} into {2}", typeof(OrderInfo).Name, entity.OrderID, "备份数据库"));
                            allEntitiesInBackup.DeleteObject(oldentity);
                            Console.WriteLine(string.Format("删除 {0}：{1} from {2}", typeof(OrderInfo).Name, entity.OrderID, "原来的数据库"));
                        }
                        else
                        {
                            Console.WriteLine(string.Format("更新 {0}：{1} into {2}", typeof(OrderInfo).Name, entity.OrderID, "备份数据库"));
                            allEntitiesInBackup.DeleteObject(oldentity);
                            Console.WriteLine(string.Format("删除 {0}：{1} from {2}", typeof(OrderInfo).Name, entity.OrderID, "原来的数据库"));
                        }                         
                    }
                    catch (Exception ex1)
                    {
                        Console.WriteLine(ex1.Message);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.WriteLine(string.Format("更新 交易 {0} 中的 订单信息 结束", tid));
            Console.WriteLine();
        }

        protected void CopyOutSentInfo(TaobaoModelContainer toBackupContainer, BackupModel.taobaotool_backupEntities backupToContainer, Int64 tid)
        {
            Console.WriteLine(string.Format("更新 交易 {0} 中的 发货信息 开始", tid));
            try
            {
                var allEntitiesInBackup = toBackupContainer.CreateObjectSet<OutSent>();
                var allBackupToEntities = backupToContainer.CreateObjectSet<BackupModel.OutSent>();

                foreach (var oldentity in allEntitiesInBackup.Where(o => o.OutSentId == tid
                                                                         && o.Message =="发货成功").ToList())
                {
                    try
                    {
                        var entity = (from s in allBackupToEntities
                                      where s.OutSentId == oldentity.OutSentId
                                      select s).FirstOrDefault();
                        bool needAdd = entity == null;
                        if (needAdd)
                        {
                            entity = allBackupToEntities.CreateObject();
                        }
                        CloneObject<OutSent, BackupModel.OutSent>(oldentity, entity, needAdd);
                        if (needAdd)
                        {
                            allBackupToEntities.AddObject(entity);
                            Console.WriteLine(string.Format("插入 {0}：{1} into {2}", typeof(OrderInfo).Name, entity.OutSentId, "备份数据库"));
                            allEntitiesInBackup.DeleteObject(oldentity);
                            Console.WriteLine(string.Format("删除 {0}：{1} from {2}", typeof(OrderInfo).Name, entity.OutSentId, "原来的数据库"));
                        }
                        else
                        {
                            Console.WriteLine(string.Format("更新 {0}：{1} into {2}", typeof(OrderInfo).Name, entity.OutSentId, "备份数据库"));
                            allEntitiesInBackup.DeleteObject(oldentity);
                            Console.WriteLine(string.Format("删除 {0}：{1} from {2}", typeof(OrderInfo).Name, entity.OutSentId, "原来的数据库"));
                        }
                    }
                    catch (Exception ex1)
                    {
                        Console.WriteLine(ex1.Message);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.WriteLine(string.Format("更新 交易 {0} 中的 发货信息 结束", tid));
            Console.WriteLine();
        }

        protected void CopyModel<T,TBackup>(TaobaoModelContainer toBackupContainer, TaobaoModelContainer backupToContainer)
            where T:class
            where TBackup:class
        {
            try
            {
                var entityInfo = entityTypeSetDict[typeof(T)];
                var allToBackupEntities = toBackupContainer.CreateObjectSet<T>(entityInfo.EntitySetName);
                var allBackupToEntities = backupToContainer.CreateObjectSet<TBackup>(entityInfo.EntitySetName);
                Console.WriteLine(string.Format("更新 {0} 开始", typeof(T).Name));
                foreach (T oldentity in allToBackupEntities)
                {
                    try
                    {
                        object oldIdValue = GetPropertyValue(oldentity, entityInfo.EntityIDName);
                        PropertyInfo propertyInfo = typeof(TBackup).GetProperty(entityInfo.EntityIDName);
                        ParameterExpression parameter = Expression.Parameter(typeof(TBackup), "p");
                        Expression body = Expression.Equal(Expression.Property(parameter, propertyInfo), Expression.Constant(oldIdValue));
                        Expression<Func<TBackup, bool>> predicate = Expression.Lambda<Func<TBackup, bool>>(body, parameter);
                        var method = predicate.Compile(); 

                        var entity = allBackupToEntities.Where(predicate).FirstOrDefault();
                        bool needAdd = entity == null;
                        if (needAdd)
                        {
                            entity = Activator.CreateInstance<TBackup>();//allBackupToEntities.CreateObject<T>();
                        }
                        CloneObject(oldentity, entity, needAdd);
                        if (needAdd)
                        {
                            backupToContainer.AddObject(entityInfo.EntitySetName, entity);
                        }
                        backupToContainer.SaveChanges();
                    }
                    catch (Exception innerEx)
                    {
                        Console.WriteLine(innerEx.Message);
                    }
                }
                Console.WriteLine(string.Format("更新 {0} 结束",typeof(T).Name));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        protected Dictionary<Type, EntityInfo> entityTypeSetDict = new Dictionary<Type, EntityInfo>();
        #endregion

        #region Page Load

        protected TextBoxWriter customTextWriter;
        protected DateTime BackupDateFrom = DateTime.Now.AddDays(-30);

        private void BackupForm_Load(object sender, EventArgs e)
        {
            this.customTextWriter = new TextBoxWriter(this.OutputTextBox);
            Console.SetOut(this.customTextWriter);
            entityTypeSetDict = new Dictionary<Type, EntityInfo>();
            entityTypeSetDict.Add(typeof(Distributor), new EntityInfo() { EntitySetName = "Distributors", EntityIDName = "distributor_id" });
            entityTypeSetDict.Add(typeof(OrderInfo), new EntityInfo() { EntitySetName = "OrderInfos", EntityIDName = "OrderID" });
            entityTypeSetDict.Add(typeof(OutSent), new EntityInfo() { EntitySetName = "OutSents", EntityIDName = "OutSentId" });
            entityTypeSetDict.Add(typeof(Refund), new EntityInfo() { EntitySetName = "Refunds", EntityIDName = "ID" });
            entityTypeSetDict.Add(typeof(Sender), new EntityInfo() { EntitySetName = "Senders", EntityIDName = "SenderID" });
            entityTypeSetDict.Add(typeof(Shop), new EntityInfo() { EntitySetName = "Shops", EntityIDName = "ShopId" });
            entityTypeSetDict.Add(typeof(Trade), new EntityInfo() { EntitySetName = "Trades", EntityIDName = "Tid" });

            string backupfrom = ConfigurationManager.AppSettings["backupFrom"];
            int backupFromDays = 30;
            if (!String.IsNullOrEmpty(backupfrom) && Int32.TryParse(backupfrom, out backupFromDays))
            {
                BackupDateFrom = DateTime.Now.AddDays(-backupFromDays);
            }
              

        }

        protected object GetPropertyValue(object target, string propertyName)
        {
            try
            {
                PropertyInfo propertyInfo = target.GetType().GetProperty(propertyName);
                return propertyInfo.GetValue(target, null);
            }
            catch (Exception e)
            { 
            }
            return null;
        }

        protected void ClearOutput()
        {
            this.OutputTextBox.Text = string.Empty;
        }

        protected void CloneObject<TSource, TTarget>(TSource source, TTarget target, bool isAdd)
        {
            try
            {
                var keyName = entityTypeSetDict[typeof(TSource)].EntityIDName;
                var allSourcePropertyInfos = typeof(TSource).GetProperties();
                foreach (var sourcePropertyInfo in allSourcePropertyInfos)
                {
                    var targetPropertyInfo = typeof(TTarget).GetProperty(sourcePropertyInfo.Name);
                    var allAttrs = sourcePropertyInfo.GetCustomAttributes(typeof(DataMemberAttribute),false);
                    if(allAttrs!=null && allAttrs.Length>0 && targetPropertyInfo !=null && sourcePropertyInfo.Name!= "EntityKey" )
                    {
                        if (!isAdd && keyName==sourcePropertyInfo.Name)
                        {
                            continue;
                        }
                        var sourceValue = sourcePropertyInfo.GetValue(source, null);
                        targetPropertyInfo.SetValue(target, sourceValue, null);
                    }
                }
            }
            catch (Exception e)
            { 
            }
        }

        #endregion

        private void ClearLogButton_Click(object sender, EventArgs e)
        {
            OutputTextBox.Text = String.Empty;
        }

        private void StopButton_Click(object sender, EventArgs e)
        {
            if (thread != null)
            {
                if (this.StopButton.Text == "暂停")
                {
                    thread.Suspend();
                    this.StopButton.Text = "继续";
                }
                else
                {
                    thread.Suspend();
                    this.StopButton.Text = "暂停";
                }
            }
        }
         

    }

    public class EntityInfo
    {
        public string EntitySetName { get; set; }
        public string EntityIDName { get; set; }
    }

    public static class ExpressionExtension
    {
        public static Expression EAndProperty<T>(this Expression expression, string propertyName, object value)
        {
            PropertyInfo propertyInfo = typeof(T).GetProperty(propertyName);
            ParameterExpression parameter = Expression.Parameter(typeof(T), "p");
            Expression rightExpression = Expression.Equal(Expression.Property(parameter, propertyInfo), Expression.Constant(value));
            return Expression.And(expression, rightExpression);
        }
    } 
}
